using System;
using System.Diagnostics;


namespace Caching.Extensions.Core.Impl
{
    /// <summary>
    /// Remote cache performance logger
    /// </summary>
    public class RemoteCachePerformanceLogger : PerfCounterHelper
    {
        #region Internal data 

        private readonly PerformanceCounter m_errorsPerSecond;
        private readonly PerformanceCounter m_errorsTotal;
        private readonly PerformanceCounter m_histPerSecond;
        private readonly PerformanceCounter m_hitsTotal;
        private readonly PerformanceCounter m_missesPerSecond;
        private readonly PerformanceCounter m_missesTotal;
        private readonly PerformanceCounter m_putsPerSecond;
        private readonly PerformanceCounter m_queryUpdateHitsPerSecond;
        private readonly PerformanceCounter m_queryUpdateMissesPerSecond;
        private readonly PerformanceCounter m_regionOperationsTotal;
        private readonly PerformanceCounter m_removesPerSecond;

        #endregion Internal data


        /// <summary>
        /// Initializes a new instance of the <see cref="RemoteCachePerformanceLogger"/> class.
        /// </summary>
        /// <param name="instanceName">Cache instance name.</param>
        /// <param name="readOnly"></param>
        public RemoteCachePerformanceLogger(string instanceName, bool readOnly)
        {
            m_histPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.HitsPerSecond, instanceName, readOnly);
            m_hitsTotal = new PerformanceCounter(RemoteCachePerfCounters.CategoryName, RemoteCachePerfCounters.HitsTotal,
                instanceName, readOnly);
            m_missesPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.MissesPerSecond, instanceName, readOnly);
            m_missesTotal = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.MissesTotal, instanceName, readOnly);
            m_queryUpdateHitsPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.QueryUpdateHitsPerSecond, instanceName, readOnly);
            m_queryUpdateMissesPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.QueryUpdateMissesPerSecond, instanceName, readOnly);
            m_putsPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.PutsPerSecond, instanceName, readOnly);
            m_removesPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.RemovesPerSecond, instanceName, readOnly);
            m_regionOperationsTotal = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.RegionOperationsTotal, instanceName, readOnly);
            m_errorsTotal = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.ErrorsTotal, instanceName, readOnly);
            m_errorsPerSecond = new PerformanceCounter(RemoteCachePerfCounters.CategoryName,
                RemoteCachePerfCounters.ErrorsPerSecond, instanceName, readOnly);
        }


        #region Counters

        protected internal PerformanceCounter ErrorsTotal
        {
            get { return m_errorsTotal; }
        }

        protected internal PerformanceCounter ErrorsPerSecond
        {
            get { return m_errorsPerSecond; }
        }

        protected internal PerformanceCounter HitsTotal
        {
            get { return m_hitsTotal; }
        }

        protected internal PerformanceCounter HistPerSecond
        {
            get { return m_histPerSecond; }
        }

        protected internal PerformanceCounter MissesTotal
        {
            get { return m_missesTotal; }
        }

        protected internal PerformanceCounter MissesPerSecond
        {
            get { return m_missesPerSecond; }
        }

        protected internal PerformanceCounter QueryUpdateHitsPerSecond
        {
            get { return m_queryUpdateHitsPerSecond; }
        }

        protected internal PerformanceCounter QueryUpdateMissesPerSecond
        {
            get { return m_queryUpdateMissesPerSecond; }
        }

        protected internal PerformanceCounter PutsPerSecond
        {
            get { return m_putsPerSecond; }
        }

        protected internal PerformanceCounter RemovesPerSecond
        {
            get { return m_removesPerSecond; }
        }

        protected internal PerformanceCounter RegionOperationsTotal
        {
            get { return m_regionOperationsTotal; }
        }

        #endregion


        /// <summary>
        /// Cache error
        /// </summary>
        public void OnError()
        {
            ErrorsTotal.Increment();
            ErrorsPerSecond.Increment();
        }


        /// <summary>
        /// Cache hit
        /// </summary>
        public void OnHit()
        {
            HitsTotal.Increment();
            HistPerSecond.Increment();
        }


        /// <summary>
        /// Cache miss
        /// </summary>
        public void OnMiss()
        {
            MissesTotal.Increment();
            MissesPerSecond.Increment();
        }


        /// <summary>
        /// Query update hit
        /// </summary>
        public void OnQueryUpdateHit()
        {
            QueryUpdateHitsPerSecond.Increment();
        }


        /// <summary>
        /// Query update miss
        /// </summary>
        public void OnQueryUpdateMiss()
        {
            QueryUpdateMissesPerSecond.Increment();
        }


        /// <summary>
        /// Cache put
        /// </summary>
        public void OnPut()
        {
            PutsPerSecond.Increment();
        }


        /// <summary>
        /// Item removed 
        /// </summary>
        public void OnRemove()
        {
            RemovesPerSecond.Increment();
        }


        /// <summary>
        /// Created cache region
        /// </summary>
        public void OnCreateRegion()
        {
            RegionOperationsTotal.Increment();
        }


        /// <summary>
        /// Removed cache region
        /// </summary>
        public void OnRemoveRegion()
        {
            RegionOperationsTotal.Increment();
        }
    }
}